package org.gfb;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import com.google.appengine.repackaged.org.json.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.appengine.repackaged.org.json.JSONArray;
import com.google.appengine.repackaged.org.json.JSONException;
import com.google.appengine.repackaged.org.json.JSONObject;

@SuppressWarnings("serial")


public class GFBServlet extends HttpServlet {
	protected String ARTICLEURL = "articleurl";
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
		throws IOException {
		String articleURL;
		resp.setContentType("text/plain");

		try{
			articleURL = req.getParameter(ARTICLEURL);
			//resp.getWriter().println(articleURL);
		} catch(Exception ex) {
			articleURL = "";
		}
		if(articleURL != "") {
			String result = callHeadUP(req, resp, articleURL);
			resp.getWriter().println(result);
		} 
	}
	
	private String callHeadUP(HttpServletRequest req , HttpServletResponse resp, String articleURL) throws IOException {
		
		Connection connection;
		ArrayList<Connection> connectionList = new ArrayList<Connection>();
		String jsonresponse = "";
		String personName1, personName2;
		try {
            URL url = new URL("http://api.headup.com/Services/RealTime/API/EntitiyExtraction/Extract.ashx?categorize=normal&targeturl="+articleURL);
            //resp.getWriter().println(url.toString());
            BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
            String line = reader.readLine();
            String xmlData = line;
            while (line != null) {
            	line = reader.readLine();
            	xmlData += line;
            }
            reader.close();
            List<String> names = parseXML(xmlData);
           /* for (String name : names){
                resp.getWriter().println(name);
            }*/
            for(int i =0;i<names.size()-2;i++) {
            	personName1 = names.get(i);
            	for(int j=i+1;j<names.size()-1;j++) {
            		personName2 = names.get(j);
            		if(queryAreFriends(personName1, personName2)){
            			connection = new Connection(personName1, personName2);
            			connectionList.add(connection);
            		}
            	}
            }
            jsonresponse = constructJsonResponse(connectionList);
		} catch (MalformedURLException e) {
        	resp.getWriter().println("Exception1");
        	resp.getWriter().println(e.getMessage());
        } catch (IOException e) {
        	resp.getWriter().println("Exception2");
        	resp.getWriter().println(e.getMessage());
        } catch(Exception ex) {
        	resp.getWriter().println("Exception3");
        	resp.getWriter().println(ex.getMessage());
        }
        return jsonresponse; 
	}
	
	private List<String> parseXML(String XMLFile) throws JSONException {
		ArrayList<String> names = new ArrayList<String>();
			JSONObject json = XML.toJSONObject(XMLFile);
			JSONObject resultJson = (JSONObject)json.get("Results");
			JSONObject entitiesJson = (JSONObject)resultJson.get("Entities");
			Object entityObj = entitiesJson.get("Entity");
			if (entityObj instanceof JSONArray){
				JSONArray entityArray = (JSONArray) entityObj;
				for (int i = 0 ; i < entityArray.length() ; i++){
					JSONObject entity = (JSONObject) entityArray.get(i);
					if (entity.toString().indexOf("R:Category:Living_people") != -1){
						names.add(entity.getString("Name"));
					}					
				}
			}
		return names;
	}


	private boolean queryAreFriends(String person1, String person2) {
		boolean areFriends = false;
		// The FreeBase query to ask if celebrity A is a friend of celebrity B
        try {
        	String query = "[{" + 
        		"\"type\": \"/celebrities/celebrity\"," +
        		"\"guid\": null," +
        		"\"ns0:type\": \"/common/topic\"," +
        		"\"name\": \""+ person1 +"\"," +
        		"\"/celebrities/celebrity/celebrity_friends\": [{" +
        		"\"guid\": null," +
        		"\"friend\":\"" + person2 + "\"" +
        		"}]" +
        		"}]";
        	String query_envelope = "{\"query\":" + query + "}";
        	System.out.println("out:" + query_envelope);
        	
        	query_envelope = URLEncoder.encode(query_envelope, "UTF-8");
            URL url = new URL(" https://www.sandbox-freebase.com/api/service/mqlread?query=" + query_envelope);
            BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
            
            String line;
            StringBuffer response = new StringBuffer();

            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            System.out.println(response);
            
            // Now we have the response
            JSONObject jsonResponse = new JSONObject(response.toString());
            
            JSONArray result = jsonResponse.getJSONArray("result");
            if (result.length() > 0){
            	areFriends = true;
            }
            

        } catch (MalformedURLException e) {
			e.printStackTrace();
        } catch (IOException e) {
			e.printStackTrace();
        } catch (JSONException e) {
			e.printStackTrace();
		}		
      
        return areFriends;	
	}
	
	/*
	 * Constructs a JSON formatted String from a list of Connection Objects 
	 */
	private String constructJsonResponse(List<Connection> connections){
		JSONObject response = new JSONObject();
		JSONArray connectionsArray = new JSONArray();
		
		try{
			for (Connection conn: connections){
				JSONArray connection = new JSONArray();
				connection.put(conn.getPerson1());
				connection.put(conn.getPerson2());
				
				JSONObject connectionObject = new JSONObject();
				connectionObject.put("connection", connection);
				
				connectionsArray.put(connectionObject);
			}
			
			response.put("relationships", connectionsArray);
		}
		catch (JSONException e) {
			e.printStackTrace();
		}
		
		return response.toString();
	}
	
	
}

class Connection {
	
	private String person1;
	private String person2;
	
	public Connection(String p1, String p2){
		person1 = p1;
		person2 = p2;
	}

	public String getPerson1() {
		return person1;
	}

	public String getPerson2() {
		return person2;
	}
	
	
	
}
